//
// Created by 86131 on 2023/9/16.
//
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXOP 100 //操作序列可能的最大长度
#define INFINITY 9999;//表示正无穷
//类型依次对应运算数，运算符，字符串结尾
typedef enum {num,opr,end1}  Type;
//
// Created by 86131 on 2023/9/16.
//
#include <iostream>
using namespace std;
typedef int ElementType;
typedef int Position;
typedef struct SNode * PtrToSNode;
struct SNode {
    ElementType *Data;//存储数组元素的数组
    Position Top;//栈顶元素指针
    int MaxSize;//栈堆最大容量
};
typedef  PtrToSNode Stack;
Stack CreateStack(int MaxSize){//初始化堆
    Stack S = (Stack)malloc(sizeof (struct SNode));
    S->Data = (ElementType*) ::malloc((MaxSize* sizeof(ElementType)));//给这个堆的data分配最大项数乘以每一项的空间
    S->Top = -1;//负一代表没有元素
    S->MaxSize = MaxSize;
    return S;
}
//入栈Push
bool IsFull(Stack S){//判断栈是否满
    return (S->Top==S->MaxSize-1);
}
bool Push(Stack S,ElementType X){
    if(IsFull(S)){
        printf("栈堆满");
        return false;//入站失败
    }
    else{
        S->Data[++(S->Top)] = X;//将栈堆++，并将元素压入堆
        return true;//入栈成功
    }
}
//出栈Pop+
bool IsEmpty(Stack S){//判断栈是否空
    return (S->Top==-1);
}
ElementType Pop(Stack S){
    if(IsEmpty(S)){
        printf("栈堆空");
        return 0;
    }
    else
        return (S->Data[(S->Top)--]);//返回出去之后，在对S-Top减一
}
Type GetOp(char * Expr,int *start,char *str){
    //从start开始读入下一个对象(操作数或者运算符),并保存在字符串str中
    int i=0;
    //跳过表达式前空格
    while((str[0] = Expr[(*start)++])==' ');//将expr元素赋给str知道不出现空格为止，才开始赋值
    while(str[i]!=' '&&str[i]!='\0')//不为空格，且不到结尾
        str[++i] = Expr[(*start)++];
    if(str[i]=='\0'){//如果读到结尾
        (*start)--;//start指向结束符
    }
    str[i] = '\0';//结束一个对象的获取
    if(i==0) return end1;//读到了结束
    else if(isdigit(str[0])|| isdigit(str[1]))
        return num;//表示str中存的是一个数字
    else          //如果str不是空串，又不是数字
        return opr;//表示此时str中存的是一个运算符
}
ElementType PostfixExp(char *Expr){//调用getop函数读入后缀表达式并求值
    Stack  S;
    Type T;
    ElementType Op1,Op2;
    char str[MAXOP];
    int start = 0;
    //创建一个堆
    S  = CreateStack(MAXOP);
    Op1 = Op2 =0;
    while((T =GetOp(Expr,&start,str))!=end1){
        //当没有读到结束
        if(T==num){
            Push(S,atof(str));//将元素压入栈中
        }
        else{//当读入的不是结束也不是数字时，那么说明读取到的是符号，这个时候，去判断是什么元素，弹出元素去进行运算在放回
            if(!IsEmpty(S)) Op2 = Pop(S);//判断是否为空，弹出元素
            else Op2 = INFINITY;//弹出失败标记
            if(!IsEmpty(S)) Op1 = Pop(S);//判断是否为空，弹出元素
            else Op1 = INFINITY;
            switch(str[0]){
                case '+':
                    Push(S,Op1+Op2);//将运算结果压入栈
                    break;
                case '*':
                    Push(S,Op1*Op2);
                    break;
                case '-':
                    Push(S,Op1-Op2);
                    break;
                case '/':
                    if(Op2!=0.0){
                        //检查除法分母是否为0
                        Push(S,Op1/Op2);
                    }else{
                        printf("错误:除法分母为0\n");
                        Op2 = INFINITY;
                    }
                    break;
                default:
                    printf("错误:未知运算符%s \n",str);
                    Op2 = INFINITY;
                    break;
            }
            if(Op2 >= 9999 ){ break;}
        }
    }
    if(Op2<9999){//如果处理完了表达式并且没有出现异常
        if(!IsEmpty(S)){//此时堆也是正常的
            Op2 = Pop(S);}//记录计算结果
            else{Op2 = INFINITY;}
    }//否则标记错误
    free(S);//释放占空间
    return Op2;
}
int main()
{
    char Expr[MAXOP];
    ElementType f;
    gets(Expr);//不知道用法
    f = PostfixExp(Expr);
    if(f<9999)
        printf("%.4f\n",f);
    else
        printf("表达式错误\n");
    return 0;
}
